/*
 *       This file is part of VFC.
 *
 *        VFC is free software: you can redistribute it and/or modify
 *        it under the terms of the GNU General Public License as published by
 *        the Free Software Foundation, either version 3 of the License, or
 *        (at your option) any later version.
 *
 *        VFC is distributed in the hope that it will be useful,
 *        but WITHOUT ANY WARRANTY; without even the implied warranty of
 *        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *        GNU General Public License for more details.
 *
 *        You should have received a copy of the GNU General Public License
 *        along with VFC.  If not, see <http://www.gnu.org/licenses/>.
 */


using System;
using System.Collections.Generic;
using System.Text;

namespace VFC.Nes.Cpu.Opcode
{
    class Relative : _Relative_
    {
        private static int OldPc = 0, NewPc = 0;

        public static void BCC()
        {
            if (Cpu.Register.GetCarryFlag() == 0)
            {
                OldPc = Cpu.Register.PC;
                Branch();
                NewPc = Cpu.Register.PC;
                if (Cpu.Memory.GetMemoryPage(OldPc) == Cpu.Memory.GetMemoryPage(NewPc))
                {
                    Cpu.Core.Cycle++;
                }
                else
                {
                    Cpu.Core.Cycle += 2;
                }
            }
            else
            {
                Cpu.Register.PC += Cpu.Core.Size[Cpu.Core._Opcode_];
            }
        }

        public static void BCS()
        {
            if (Cpu.Register.GetCarryFlag() == 1)
            {
                OldPc = Cpu.Register.PC;
                Branch();
                NewPc = Cpu.Register.PC;
                if (Cpu.Memory.GetMemoryPage(OldPc) == Cpu.Memory.GetMemoryPage(NewPc))
                {
                    Cpu.Core.Cycle++;
                }
                else
                {
                    Cpu.Core.Cycle += 2;
                }
            }
            else
            {
                Cpu.Register.PC += Cpu.Core.Size[Cpu.Core._Opcode_];
            }
        }

        public static void BEQ()
        {
            if (Cpu.Register.GetZeroFlag() == 1)
            {
                OldPc = Cpu.Register.PC;
                Branch();
                NewPc = Cpu.Register.PC;
                if (Cpu.Memory.GetMemoryPage(OldPc) == Cpu.Memory.GetMemoryPage(NewPc))
                {
                    Cpu.Core.Cycle++;
                }
                else
                {
                    Cpu.Core.Cycle += 2;
                }
            }
            else
            {
                Cpu.Register.PC += Cpu.Core.Size[Cpu.Core._Opcode_];
            }
        }

        public static void BMI()
        {
            if (Cpu.Register.GetNegativeFlag() == 1)
            {
                OldPc = Cpu.Register.PC;
                Branch();
                NewPc = Cpu.Register.PC;
                if (Cpu.Memory.GetMemoryPage(OldPc) == Cpu.Memory.GetMemoryPage(NewPc))
                {
                    Cpu.Core.Cycle++;
                }
                else
                {
                    Cpu.Core.Cycle += 2;
                }
            }
            else
            {
                Cpu.Register.PC += Cpu.Core.Size[Cpu.Core._Opcode_];
            }
        }

        public static void BNE()
        {
            if (Cpu.Register.GetZeroFlag() == 0)
            {
                OldPc = Cpu.Register.PC;
                Branch();
                NewPc = Cpu.Register.PC;
                if (Cpu.Memory.GetMemoryPage(OldPc) == Cpu.Memory.GetMemoryPage(NewPc))
                {
                    Cpu.Core.Cycle++;
                }
                else
                {
                    Cpu.Core.Cycle += 2;
                }
            }
            else
            {
                Cpu.Register.PC += Cpu.Core.Size[Cpu.Core._Opcode_];
            }
        }

        public static void BPL()
        {
            if (Cpu.Register.GetNegativeFlag() == 0)
            {
                OldPc = Cpu.Register.PC;
                Branch();
                NewPc = Cpu.Register.PC;
                if (Cpu.Memory.GetMemoryPage(OldPc) == Cpu.Memory.GetMemoryPage(NewPc))
                {
                    Cpu.Core.Cycle++;
                }
                else
                {
                    Cpu.Core.Cycle += 2;
                }
            }
            else
            {
                Cpu.Register.PC += Cpu.Core.Size[Cpu.Core._Opcode_];
            }
        }

        public static void BVC()
        {
            if (Cpu.Register.GetOverflowFlag() == 0)
            {
                OldPc = Cpu.Register.PC;
                Branch();
                NewPc = Cpu.Register.PC;
                if (Cpu.Memory.GetMemoryPage(OldPc) == Cpu.Memory.GetMemoryPage(NewPc))
                {
                    Cpu.Core.Cycle++;
                }
                else
                {
                    Cpu.Core.Cycle += 2;
                }
            }
            else
            {
                Cpu.Register.PC += Cpu.Core.Size[Cpu.Core._Opcode_];
            }
        }

        public static void BVS()
        {
            if (Cpu.Register.GetOverflowFlag() == 1)
            {
                OldPc = Cpu.Register.PC;
                Branch();
                NewPc = Cpu.Register.PC;
                if (Cpu.Memory.GetMemoryPage(OldPc) == Cpu.Memory.GetMemoryPage(NewPc))
                {
                    Cpu.Core.Cycle++;
                }
                else
                {
                    Cpu.Core.Cycle += 2;
                }
            }
            else
            {
                Cpu.Register.PC += Cpu.Core.Size[Cpu.Core._Opcode_];
            }
        }
    }
}
